#ifndef __FD_MANAGWR_H__
#define __FD_MANAGWR_H__

#include "singleton.h"

#include <memory>
#include <shared_mutex>
#include <vector>

//这个类是辅助hook使用的  
//判断fd是否为sock文件描述符或者文件描述符是否存在
//如果文件描述为sock类型则使用hook，否则不使用hook

//文件描述符属性类
class FdCtx: public std::enable_shared_from_this<FdCtx>
{
public:
    using ptr = std::shared_ptr<FdCtx>;

    //通过文件句柄构造FdCtx
    FdCtx(int fd);
    ~FdCtx();

    //是否初始化完成
    bool isInit() const { return m_isInit;}

    //是否socket
    bool isSocket() const { return m_isSocket;}

    //是否已关闭
    bool isClose() const { return m_isClosed;}

    //设置用户主动设置非阻塞
    void setUserNonblock(bool v) { m_userNonblock = v;}

    //获取是否用户主动设置的非阻塞(异步)
    bool getUserNonblock() const { return m_userNonblock;}

    //设置系统非阻塞
    void setSysNonblock(bool v) { m_sysNonblock = v;}

    //获取系统非阻塞
    bool getSysNonblock() const { return m_sysNonblock;}

    //设置超时时间
    //type 类型SO_RCVTIMEO(读超时), SO_SNDTIMEO(写超时)
    //v 时间  毫秒
    void setTimeout(int type, uint64_t v);

    //获取超时时间
    //type 类型SO_RCVTIMEO(读超时), SO_SNDTIMEO(写超时)
    //返回超时时间  毫秒
    uint64_t getTimeout(int type);

private:
    //初始化
    bool init();

    //xxx: 1表示指定变量占用 1 位的存储空间
    bool m_isInit: 1;       //是否初始化
    bool m_isSocket: 1;     //是否为socket
    bool m_sysNonblock: 1;  //是否hook非阻塞 (是否为异步   sock fd默认为true)
    bool m_userNonblock: 1; //用户是否将fd类型主动设置为非阻塞 (默认为false)
    bool m_isClosed: 1;     //描述符是否关闭
    int  m_fd;              //文件描述符
    uint64_t m_recvTimeout; //读超时时间  毫秒
    uint64_t m_sendTimeout; //写超时时间  毫秒
};


//文件描述符管理类
class FdManager
{
public:
    FdManager();

    //获取/创建文件句柄类FdCtx
    //fd 文件句柄
    //auto_create 是否自动创建
    //返回对应文件描述符FdCtx::ptr
    FdCtx::ptr get(int fd, bool auto_create = false);

    //删除对应文件描述符
    void del(int fd);
private:
    std::shared_mutex m_sharedMutex;    //读写锁
    std::vector<FdCtx::ptr> m_fdDatas;  //文件描述符集合
};

//将FdMgr重命名为FdManager单例类
using FdMgr = Singleton<FdManager>;

#endif //__FD_MANAGWR_H__